package com.jin.webvideo.base.linkedfile.util;

import com.jin.webvideo.base.linkedfile.io.SeekableInputStream;
import com.jin.webvideo.base.linkedfile.LinkedFile;
import com.jin.webvideo.base.linkedfile.LinkedItem;
import com.jin.webvideo.base.linkedfile.LinkedProperties;
import com.jin.webvideo.base.linkedfile.io.RandomAccessVFile;
import com.jin.webvideo.base.linkedfile.io.SeekableDataInputStream;
import org.springframework.util.StreamUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Set;

public class VFileWriter {
    public void write(LinkedFile linkedFile, File storeFile) throws IOException {
        RandomAccessVFile file = new RandomAccessVFile(storeFile, "rw");
        file.seek(0);
        // 写入magic
        file.writeByte(LinkedFile.MAGIC);
        // 写入版本号
        file.writeShort(linkedFile.getVersion());
        int size = linkedFile.getDirZone().size();
        // 写入总项数
        file.writeShort(size);
        linkedFile.setLastModified(System.currentTimeMillis());
        // 写入最后修改时间
        file.writeLong(linkedFile.getLastModified());

        byte[] desc = linkedFile.getDescription().getBytes(StandardCharsets.UTF_8);
        // 写入长度
        file.writeShort(desc.length);
        //写入数据
        file.write(desc);
        // 存储此时的写入位置
        file.store();

        // 计算属性区的开始位置
        long offset =  size *28 + file.getFilePointer();

        file.seek(offset);
        for (LinkedItem item : linkedFile.getDirZone()) {
            // 设置属性指针
            item.setPoint(offset);
            // 写入属性串
            byte[] s = convert(item.getProperties()).getBytes(StandardCharsets.UTF_8);
            if (s.length == 0) {
                continue;
            }
            file.writeShort(s.length);
            file.write(s);
            // 指针移向下一条记录的位置属性 （属性 = 长度（无符号int）+值）
            offset += s.length + 2;
        }

        // 恢复位置
        file.reStore();
        for (LinkedItem item : linkedFile.getDirZone()) {
            file.writeLong( item.getStart());
            file.writeInt((int) item.getOffset());
            file.writeLong( item.getLength());
            file.writeLong( item.getPoint());
        }
        file.close();
    }

    public void split(File file, File storeFile, long size, String suffix, File headFile) throws IOException {
        FileInputStream stream = new FileInputStream(file);
        LinkedFile linkedFile1 = new LinkedFile();
        linkedFile1.setDescription(file.getName());
        List<LinkedItem> dirZone = linkedFile1.getDirZone();
        for (long i = 0, l = file.length() / size; i <= l; i++) {
            int index = storeFile.getName().indexOf(".");

            File temp = new File(storeFile.getParentFile(), storeFile.getName().substring(0, index) + i + suffix);
            if (!temp.exists()) {
                temp.createNewFile();
            }

            FileOutputStream outputstream = new FileOutputStream(temp);

            long offset = 0L;
            long length = StreamUtils.copyRange(stream, outputstream,0, size-1);
            LinkedItem item = new LinkedItem(linkedFile1, i * size, offset, length);

            LinkedProperties p = new LinkedProperties();
            p.put("uri", temp.getName());
            item.setProperties(p);
            dirZone.add(item);

            outputstream.close();
        }
        stream.close();
        this.write(linkedFile1, storeFile);

    }

    private String convert(LinkedProperties linkedProperties) {
        Set<String> keys = linkedProperties.keySet();
        if (keys.size() == 0) {
            return "";
        }
        String[] kv = new String[keys.size()];
        int i = 0;
        for (String key : keys) {
            String val = linkedProperties.get(key);
            kv[i++] = key + "\2" + val;
        }
        return String.join("\4", kv) + "\4";
    }

    public static void main(String[] args) throws IOException {
        File file = new File("E:\\download\\theWanderingEarth2\\theWanderingEarth2.pkg");
        SeekableInputStream inputStream = new SeekableInputStream(new FileInputStream(file), (int) file.length(), false);
        LinkedFile linkedFile = new LinkedFile(new SeekableDataInputStream(inputStream), null);
        linkedFile.load();
        System.out.println(linkedFile);

        /*VFileWriter writer = new VFileWriter();
        writer.split(new File("E:\\download\\流浪地球2.mp4"), new File("E:\\download\\theWanderingEarth2\\theWanderingEarth2.pkg"),1024*1024*60,  ".pkg", new File("C:\\Users\\jin\\Desktop\\bg.jpg"));
*/        /*file.setVersion(1);
        List<DirItem> dirZone = file.getDirZone();
        dirZone.add(new DirItem(file, 0, 1, 0));
        dirZone.add(new DirItem(file, 1, 1, 0));
        Properies p = new Properies();
        p.put("uri", "123");
        dirZone.get(0).setProperties(p);

        Properies p2 = new Properies();
        p2.put("uri", "321");
        dirZone.get(1).setProperties(p2);
        writer.write(file);*/
    }
}
